package com.siyoumi.app.modules.app_book.service;

import com.siyoumi.app.entity.*;
import com.siyoumi.app.modules.account.service.SvcSysStore;
import com.siyoumi.app.modules.account.vo.VaSysStore;
import com.siyoumi.app.modules.app_book.vo.VaBookStore1;
import com.siyoumi.app.modules.app_book.vo.VoBookOrderRefundRule;
import com.siyoumi.app.modules.app_book.vo.VoBookSpuAudit;
import com.siyoumi.app.modules.user.service.SvcSysSale;
import com.siyoumi.app.modules.user.vo.VoSale;
import com.siyoumi.app.modules.user.vo.VoSaleAudit;
import com.siyoumi.app.service.BookStoreService;
import com.siyoumi.app.service.BookStoreTxtService;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XBean;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.Min;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

//
@Slf4j
@Service
public class SvcBookStore
        implements IWebService {
    static public SvcBookStore getBean() {
        return XSpringContext.getBean(SvcBookStore.class);
    }

    static public BookStoreService getApp() {
        return BookStoreService.getBean();
    }

    public List<Map<String, Object>> getList() {
        JoinWrapperPlus<BookStore> query = listQuery();
        query.select("bstore_id", "bstore_name");
        return getApp().getMaps(query);
    }

    /**
     * 分销员分佣比例
     *
     * @param entityStore
     * @param level
     */
    static public BigDecimal getSalesRate(BookStore entityStore, Integer level) {
        BigDecimal rate = BigDecimal.ZERO;
        switch (level) {
            case 0: //普通
                rate = entityStore.getBstore_sales0_rate();
                break;
            case 5: //黄金
                rate = entityStore.getBstore_sales1_rate();
                break;
        }

        return rate;
    }

    /**
     * 默认退款规则
     *
     * @return
     */
    public List<VoBookOrderRefundRule> getRefundRuleDef() {
        List<VoBookOrderRefundRule> list = new ArrayList<>();
        {
            VoBookOrderRefundRule item = new VoBookOrderRefundRule();
            item.setDay_min(0);
            item.setDay_max(5);
            item.setRate(BigDecimal.valueOf(20)); //10%
            list.add(item);
        }
        {
            VoBookOrderRefundRule item = new VoBookOrderRefundRule();
            item.setDay_min(6);
            item.setDay_max(10);
            item.setRate(BigDecimal.valueOf(10)); //10%
            list.add(item);
        }

        return list;
    }

    /**
     * 获取退款规则
     *
     * @param refundRule
     */
    public List<VoBookOrderRefundRule> getRefundRule(String refundRule) {
        if (XStr.isNullOrEmpty(refundRule)) {
            return getRefundRuleDef();
        }

        return XJson.parseArray(refundRule, VoBookOrderRefundRule.class);
    }

    public BigDecimal getRefundRate(String storeId, LocalDateTime dateBegin) {
        BookStore entityStore = getApp().getEntity(storeId);
        List<VoBookOrderRefundRule> refundRule = getRefundRule(entityStore.getBstore_refund_rule());
        return getRefundRate(refundRule, dateBegin);
    }

    /**
     * 获取退款手续费率
     *
     * @param dateBegin
     */
    public BigDecimal getRefundRate(List<VoBookOrderRefundRule> refundRule, LocalDateTime dateBegin) {
        Duration between = XDate.between(XDate.today(), dateBegin);
        long days = between.toDays(); //离入住日还剩多少天
        if (days < 0) {
            days = 0;
        }
        log.debug("离入住还剩：{}", days);

        long daysX = days;
        VoBookOrderRefundRule refundRuleItem = refundRule.stream().filter(item -> {
            return daysX >= item.getDay_min() && daysX <= item.getDay_max();
        }).findFirst().orElse(null);
        if (refundRuleItem != null) {
            return refundRuleItem.getRate();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 有效
     *
     * @param entity
     */
    public XReturn valid(BookStore entity) {
        if (entity == null) {
            return EnumSys.ERR_VAL.getR("商家不存在");
        }
        if (entity.getBstore_del() != 0) {
            return EnumSys.ERR_VAL.getR("商家不存在[1]");
        }

        if (entity.getBstore_enable() != 1) {
            return EnumSys.ERR_VAL.getR("商家已失效");
        }

        return EnumSys.OK.getR();
    }

    public JoinWrapperPlus<BookStore> listQuery() {
        return listQuery(InputData.getIns());
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<BookStore> listQuery(InputData inputData) {
        String name = inputData.input("name");
        String hot = inputData.input("hot");
        String province = inputData.input("province");
        String city = inputData.input("city");
        String collect = inputData.input("collect");
        String foreign = inputData.input("foreign");
        String groupId = inputData.input("group_id");
        String play = inputData.input("play");
        String altitudeMin = inputData.input("altitude_min");
        String altitudeMax = inputData.input("altitude_max");
        String spuCount = inputData.input("spu_count");
        String spuDevice = inputData.input("spu_device");

        JoinWrapperPlus<BookStore> query = getApp().join();
        query.eq("bstore_x_id", XHttpContext.getX())
                .eq("bstore_del", 0);
        //排序
        query.orderByDesc("bstore_id");
        if (XStr.hasAnyText(name)) { //名称
            query.like("bstore_title", name);
        }
        if ("1".equals(hot)) { //热门
            query.eq("bstore_hot", 1);
        } else if ("all".equals(foreign)) {
            query.in("bstore_hot", 0, 1);
        }

        if (XStr.hasAnyText(province)) { //省
            List<String> provinceList = List.of(province.split(","));
            query.in("bstore_province", provinceList);

            if (XStr.hasAnyText(city)) { //市
                query.eq("bstore_city", city);
            }
        }
        if (XStr.hasAnyText(groupId)) { //分组
            query.eq("bstore_group_id", groupId);
        }
        if (XStr.hasAnyText(foreign)) { //可接待外籍
            if ("all".equals(foreign)) {
                query.in("bstore_foreign", 0, 1);
            } else {
                query.eq("bstore_foreign", foreign);
            }
        }
        if ("1".equals(collect)) { //显示收藏基地
            String sqlExists = "SELECT 1 FROM wx_app.t_sys_uv WHERE uv_type = 'store_collect' AND uv_type_id = bstore_id AND uv_uid = {0}";
            query.exists(sqlExists, getUid());
        }
        if (XStr.hasAnyText(altitudeMin) && XStr.hasAnyText(altitudeMax)) { //海拔
            query.le("bstore_altitude", altitudeMax)
                    .ge("bstore_altitude", altitudeMin);
        }
        if (XStr.hasAnyText(play)) { //商家娱乐设施
            String[] playArr = play.split(",");
            String sqlExists = "SELECT 1 FROM wx_app_x.t_book_item_zzz WHERE bizz_type = 'play' AND bizz_type_id = bstore_id AND ";
            String sqlIn = XSqlStr.in("bizz_item_id", playArr);
            sqlExists += sqlIn;
            query.exists(sqlExists, playArr);
        }
        if (XStr.hasAnyText(spuCount)) { //房型
            String[] spuCountArr = spuCount.split(",");
            String sqlExists = "SELECT 1 FROM wx_app_x.t_book_spu WHERE bspu_store_id = bstore_id AND ";
            String sqlIn = XSqlStr.in("bspu_user_count", spuCountArr);
            sqlExists += sqlIn;
            query.exists(sqlExists, spuCountArr);
        }
        if (XStr.hasAnyText(spuDevice)) { //房源设施
            String[] spuDeviceArr = spuDevice.split(",");
            String sqlExists = "SELECT 1 FROM wx_app_x.t_book_item_zzz WHERE bizz_type = 'device' AND bizz_store_id = bstore_id AND ";
            String sqlIn = XSqlStr.in("bizz_item_id", spuDeviceArr);
            sqlExists += sqlIn;
            query.exists(sqlExists, spuDeviceArr);
        }

        return query;
    }

    public XReturn save(InputData inputData, VaBookStore1 vo) {
        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
        }

        return XApp.getTransaction().execute(status -> {
            XReturn r = getApp().saveEntity(inputData, vo, false, ignoreField);
            if (r.ok()) {
                BookStore entity = r.getData("entity");
                //同步保存商家
                SvcSysStore.getBean().edit(VaSysStore.of(entity.getBstore_id(), vo.getBstore_acc_id(), entity.getBstore_name()));
            }

            //基地介绍
            BookStoreTxt entityTxt = BookStoreTxtService.getBean().getEntity(vo.getBstore_id());
            BookStoreTxt entityTxtUpdate = new BookStoreTxt();
            if (entityTxt == null) {
                entityTxtUpdate.setBstoret_id(vo.getBstore_id());
                entityTxtUpdate.setBstoret_x_id(XHttpContext.getX());
            }
            XBean.copyProperties(vo, entityTxtUpdate);
            BookStoreTxtService.getBean().saveOrUpdatePassEqualField(entityTxt, entityTxtUpdate);

            //新建省市
            BookItem entityItem = SvcBookItem.getBean().save("province", null, vo.getBstore_province());
            SvcBookItem.getBean().save("city", entityItem.getBitem_id(), vo.getBstore_city());

            if (vo.getSet_item_play() == 1) { //娱乐设施
                SvcBookItem.getBean().updateItemZZ("play", vo.getBstore_id(), vo.getBstore_id(), vo.getItem_play_ids());
            }

            //新建分销帐号
            {
                VoSale voSale = new VoSale();
                voSale.setSale_id(vo.getBstore_id());
                voSale.setSale_acc_id(vo.getBstore_acc_id());
                voSale.setSale_name(vo.getBstore_name());
                voSale.setSale_uid(vo.getBstore_id());
                voSale.setSale_type("store");
                SvcSysSale.getBean().save(voSale);
                //审核通过
                VoSaleAudit voSaleAudit = new VoSaleAudit();
                voSaleAudit.setIds(List.of(vo.getBstore_id()));
                voSaleAudit.setEnable(1);
                SvcSysSale.getBean().audit(voSaleAudit);
            }

            return r;
        });
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        getApp().delete(ids);
        SvcSysStore.getBean().delete(ids);
        //房源下架
        //SvcBookSpu.getBean()

        return r;
    }


    /**
     * 更新最1晚价格
     *
     * @param storeId
     */
    public void updateDay1Price(String storeId) {
        JoinWrapperPlus<BookSku> query = SvcBookSku.getBean().listQuery();
        query.eq("bsku_store_id", storeId).eq("bsku_enable", 1); //上架
        query.orderByAsc("bsku_day_price"); //价格最小
        BookSku entitySku = SvcBookSku.getApp().first(query);
        BigDecimal day1Price = BigDecimal.ZERO;
        if (entitySku != null) {
            day1Price = entitySku.getBsku_day_price();
        }

        BookStore entityUpdate = new BookStore();
        entityUpdate.setBstore_id(storeId);
        entityUpdate.setBstore_day1_price(day1Price);
        getApp().updateById(entityUpdate);
    }

    /**
     * 更新第1个的套餐
     *
     * @param storeId
     */
    public void updateSetIdFirst(String storeId) {
        BookSet entitySet = SvcBookSet.getBean().getFirst(storeId);

        String setId = "";
        if (entitySet != null) {
            setId = entitySet.getBset_id();
        }

        BookStore entityUpdate = new BookStore();
        entityUpdate.setBstore_id(storeId);
        entityUpdate.setBstore_set_id(setId);
        getApp().updateById(entityUpdate);
    }


    /**
     * 审核
     *
     * @param vo
     */
    @Transactional(rollbackFor = Exception.class)
    public XReturn audit(VoBookSpuAudit vo) {
        List<BookStore> list = getApp().get(vo.getIds());
        if (list.isEmpty()) {
            return EnumSys.OK.getR();
        }

        for (BookStore entity : list) {
            if (Objects.equals(entity.getBstore_enable(), vo.getEnable())) {
                continue;
            }

            BookStore entityUpdate = new BookStore();
            entityUpdate.setBstore_id(entity.getKey());
            entityUpdate.setBstore_enable(vo.getEnable());
            getApp().updateById(entityUpdate);
        }

        return EnumSys.OK.getR();
    }
}
